package ma.platform.server.student.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.pig4cloud.plugin.excel.vo.ErrorMessage;
import jakarta.annotation.Resource;
import ma.platform.server.core.exception.ErrorCodes;
import ma.platform.server.core.util.MsgUtils;
import ma.platform.server.core.util.R;
import ma.platform.server.core.util.StreamUtils;
import ma.platform.server.student.dto.TbStudentDto;
import ma.platform.server.student.entity.*;
import ma.platform.server.student.req.QueryStudentReq;
import ma.platform.server.student.service.*;
import ma.platform.server.student.mapper.TbStudentMapper;
import ma.platform.server.student.vo.StudentExcelVo;
import ma.platform.server.upms.api.entity.SysRole;
import ma.platform.server.upms.api.vo.RoleExcelVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @description 针对表【tb_student(学生信息表)】的数据库操作Service实现
 * @createDate 2024-08-27 17:01:05
 */
@Service
public class TbStudentServiceImpl extends ServiceImpl<TbStudentMapper, TbStudent>
        implements TbStudentService {

    @Resource
    private TbSchoolService schoolService;

    @Resource
    private TbGradeService tbGradeService;

    @Resource
    private TbClassesService tbClassesService;

    @Resource
    private TbStudentParentService tbStudentParentService;
    @Resource
    private TbParentService tbParentService;

    @Override
    public Page<TbStudentDto> pageList(Page page, QueryStudentReq req) {
        Page<TbStudentDto> pageResut = baseMapper.selectPageList(page, req);
        if (CollectionUtils.isEmpty(pageResut.getRecords())) {
            return pageResut;
        }
        List<Long> idList = StreamUtils.convert2List(pageResut.getRecords(), TbStudentDto::getId);
        List<TbStudentParent> studentParents = tbStudentParentService.list(Wrappers.<TbStudentParent>lambdaQuery()
                .in(TbStudentParent::getStudentId, idList));
        if (CollectionUtils.isEmpty(studentParents)) {
            return pageResut;
        }
        List<Long> parentIdList = StreamUtils.convert2List(studentParents, TbStudentParent::getParentId);
        if (CollectionUtils.isEmpty(parentIdList)) {
            return pageResut;
        }
        List<TbParent> tbParents = tbParentService.listByIds(parentIdList);
        Map<Long, String> nickeMap = StreamUtils.getMap(StreamUtils.filterList(tbParents,item-> StringUtils.isNotBlank(item.getNickName())), TbParent::getId, TbParent::getNickName);
        Map<Long, List<TbStudentParent>> studentParentMap = StreamUtils.getGroupMap(studentParents, TbStudentParent::getStudentId);

        for (TbStudentDto record : pageResut.getRecords()) {
            List<TbStudentParent> tbStudentParents = studentParentMap.get(record.getId());
            if (CollectionUtils.isNotEmpty(tbStudentParents)) {
                String nickName = tbStudentParents.stream().map(item -> nickeMap.getOrDefault(item.getParentId(), ""))
                        .collect(Collectors.joining(","));
                record.setParentName(nickName);
            }
        }
        return pageResut;
    }

    @Override
    public void removeBind(Long id) {
        baseMapper.removeBind(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R importRole(List<StudentExcelVo> excelVOList, BindingResult bindingResult) {
        Map<String, Long> schoolMap = getSchoolMap(excelVOList);
        List<TbGrade> gradeList = tbGradeService.list(Wrappers.<TbGrade>lambdaQuery().in(TbGrade::getSchoolId, schoolMap.values()));
        Map<String, Long> gradeNameMap = StreamUtils.getMap(gradeList, TbGrade::getGradeName, TbGrade::getId);
        List<TbClasses> classesList = tbClassesService.list(Wrappers.<TbClasses>lambdaQuery().in(TbClasses::getGradeId, gradeNameMap.values()));
        Map<Long, List<TbClasses>> gradeClassesMap = StreamUtils.getGroupMap(classesList, TbClasses::getGradeId);
        Map<Long, Map<String, Long>> classesMap = Maps.newHashMap();
        for (Long gradeId : gradeNameMap.values()) {
            List<TbClasses> classesListByGradeId = gradeClassesMap.get(gradeId);
            Map<String, Long> classesNameMap = StreamUtils.getMap(classesListByGradeId, TbClasses::getClassesName, TbClasses::getId);
            classesMap.put(gradeId, classesNameMap);
        }
        List<TbStudent> studentList = Lists.newArrayList();
        for (StudentExcelVo studentExcelVo : excelVOList) {
            TbStudent student = new TbStudent();
            student.setStudentId(studentExcelVo.getStudentId());
            student.setName(studentExcelVo.getStudentName());
            student.setSchoolId(schoolMap.get(studentExcelVo.getSchoolName()));
            student.setGradeId(gradeNameMap.get(studentExcelVo.getGradeName()));
            Map<String, Long> classesNameMap = classesMap.get(student.getGradeId());
            student.setClassesId(classesNameMap.get(studentExcelVo.getClassesName()));
            studentList.add(student);
        }
        if (CollUtil.isNotEmpty(studentList)) {
            saveBatch(studentList);
        }
        return R.ok();
    }

    @Override
    public List<TbStudent> listStudent(Long id) {
        return baseMapper.selectStudent(id);
    }

    @Override
    public Long getStudentSchoolId(Long studentId) {
        return baseMapper.selectSchoolId(studentId);
    }

    private Map<String, Long> getSchoolMap(List<StudentExcelVo> excelVOList) {
        Set<String> schoolNameList = StreamUtils.convert2Set(excelVOList, StudentExcelVo::getSchoolName);
        List<TbSchool> schoolList = schoolService.list(Wrappers.<TbSchool>lambdaQuery().in(TbSchool::getSchoolName, schoolNameList));
        Map<String, Long> schoolMap = StreamUtils.getMap(schoolList, TbSchool::getSchoolName, TbSchool::getId);
        return schoolMap;
    }


}




